#ifndef _RUMR_H_
#define _RUMR_H_

#include "math.h"
#include "schedulingheuristic.h"

#include <map>

#define MODIFY_PHASE 0.8
#define MINIMUM 1048576

using namespace std;

typedef map<const char*,long double> ChunkMap;

class Rumr : public SchedulingHeuristic {

public:
	
	//Constructor
	Rumr(long double workload_size, long double error_rate=0);
	
	//Destructor
	~Rumr();
	
	/*Schedule Method*/
	long double  schedule(Grid *grid, Job *job);
		
	/*Simgrid simulation*/
	void doSimGridSimulation(SG_Task task_to_watch);
	
private:

	//Sg_task
	SG_Task *tasks_finished;

	//Workload
	long double workload_size;
	long double workload_computed;
	
	//Heuristic Phase
	enum {UMR,WF};
	int phase;
	
	//Table with initial chunk size for all processors
	ChunkMap initial_chunks;
	ChunkMap processor_round;
	int number_of_processors;
	int number_of_iterations;
	void calculate_all_initial_chunk_size(Grid *grid, Job *job);
	int count_processors(Grid *grid);
	long double sum_processors_speed(Grid *grid, long double tpt);

	//Calculates the next chunk size
	long double calculate_next_chunk_size( long double chunk_initial, long double speed_link, long double speed_processor,
										int number_of_processors, int number_of_iteration );
										
	//Calculates the initial chunk size
	long double calculate_initial_chunk_size( long double speed_link, long double speed_processor, int number_of_processors,
											long double workload_total );
											
	//Schedules first round
	void schedule_first_round( Grid *grid, Job *job );
	
	//Schedules until starts the second phase (Weighted Factory)
	void schedule_umr_phase( Grid *grid, Job *job ); 
	
	//Schedules the second phase
	void schedule_wf_phase( Grid *grid, Job *job );
	
	//Reinicializa all parameters
	void reinicialize();
											
	//Calculate number of iterations
	void calculate_number_of_iterations( Grid *grid, Job *job );
	
	//Calculate x^y with long double numbers
	long double powl(long double x, int y);
	
	long double get_teta(Grid *grid, long double tpt);
	long double get_sum_alpha_bi(Grid *grid, long double tpt);
	long double get_alpha(Grid *grid, Processor *proc, long double tpt);
	
};

#endif //_RUMR_H_
